/**
 * 系统名称: 企业财资
 * 模块名称: repair-boot
 * 类 名 称: WxUtils.java
 * 软件版权: 恒生电子股份有限公司
 * 修改记录:
 * 修改人员:
 * 修改说明:
 * ============ ============================================
 * zhanghong 创建
 * ============ ============================================
 */
package com.mt.repair.utils.wxPush;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mt.common.core.exception.BusinessException;
import com.mt.common.core.utils.DateUtils;
import com.mt.common.core.utils.ScheduledUtils;
import com.mt.repair.utils.GzipUtils;
import com.mt.repair.utils.wxPush.vo.WechatSendMsgVo;
import com.mt.repair.utils.wxPush.vo.WechatTemplateVo;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.io.*;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.zip.GZIPInputStream;

/**
 *
 *
 * @author zhanghong
 * @date 2023-03-21 21:27
 */
@Component
public class WxUtils implements InitializingBean {
    Logger logger = LoggerFactory.getLogger(WxUtils.class);

    private String appid="wx51634067eeeabf1f";
    private String secret="5cfdf5c3991a498cfa68b4418cbbcc6d";

    private String loveDay="2020-3-10";
    private String babyBirthDay="03-18";
    private String myBirthDay="01-25";
    @Autowired
    private RestTemplate restTemplate;
    public String getAccessToken(){
        String url=Url.ACCESS_TOKEN.replace("APPID",appid).replace("SECRET",secret);
        String res = restTemplate.getForObject(url, String.class);
        JSONObject jsonObject = JSONObject.parseObject(res);
        return jsonObject.get("access_token")!=null? (String) jsonObject.get("access_token") :"error";
    }

    public List<String> getUserList(String token){
        List<String> userList=new ArrayList<>();
        if(token.equals("error")){return userList;}
        String url=Url.USERLIST.replace("ACCESS_TOKEN",token);
        String res = restTemplate.getForObject(url, String.class);
        JSONObject jsonObject = JSONObject.parseObject(res);
        if(jsonObject.get("errcode")!=null){
            return userList;
        }
        JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("openid");
        userList= JSONObject.parseArray(jsonArray.toJSONString(), String.class);
        return userList;
    }
    public String getArea(String area) throws JobExecutionException {
        if(area==null){area="重庆";}
        String url=Url.AREA.replace("{area}",area);
        JSONObject res = restTemplate.getForObject(url, JSONObject.class);
        if(!res.get("infocode").equals("10000")){
            throw new JobExecutionException("获取地址Code异常");
        }
        JSONObject geocode = res.getJSONArray("geocodes").getJSONObject(0);
        String adcode = (String) geocode.get("adcode");
        return adcode;
    }
    public JSONObject getWeather(String adcode) throws IOException, JobExecutionException {
        String url=Url.WEATHER.replace("{adcode}",adcode);
        JSONObject res = restTemplate.getForObject(url, JSONObject.class);
        if(!res.get("infocode").equals("10000")){
            throw new JobExecutionException("获取天气异常");
        }
        return res.getJSONArray("forecasts").getJSONObject(0).getJSONArray("casts").getJSONObject(0);
    }

    public String getAstro(String astro){
        if(astro==null){astro="pisces";}
        String url=Url.CONSTELLATION.replace("ASTRO",astro);
        JSONObject res= restTemplate.getForObject(url, JSONObject.class);
        if(!res.get("code").equals(200)){return "";}
        JSONArray result = (res.getJSONObject("result")).getJSONArray("list");
        AtomicReference<String> resContent= new AtomicReference<>("");
        result.stream().filter(Objects::nonNull).forEach(json->{
            if(((JSONObject) json).get("type").toString().equals("今日概述")){
                resContent.set(((JSONObject) json).get("content").toString());
            }
        });
        return resContent.get();
    }

    public String getZaoAn(){
        JSONObject res= restTemplate.getForObject(Url.ZAOAN, JSONObject.class);
        if(!res.get("code").equals(200)){return "";}
        Map result = (Map) res.get("result");
        return (String) result.get("content");
    }
   //https://devapi.qweather.com/v7/weather/3d?location=101040900&key=31afd435ed9a4784bd8d206fbfae4564
   //{"templateId":"模板ID","astro":"星座","weatherParams":{"url":"https://devapi.qweather.com/v7/weather/3d?location=101040900&key=31afd435ed9a4784bd8d206fbfae4564",}
    public void pushMessage(String params) throws IOException, JobExecutionException {
        JSONObject paramsObject = JSONObject.parseObject(params);
        String templateId = (String) paramsObject.get("templateId");
        /*
        获取天气信息
         */

        JSONObject weatherJson= (JSONObject) paramsObject.get("weatherParams");
        String area=weatherJson.get("area")!=null? (String) weatherJson.get("area") :"重庆";
        JSONObject weatherRes=this.getWeather(this.getArea(area));
        String weather=null;String lowest=null;String highest=null;
        if(weatherRes!=null){
            weather= (String) weatherRes.get((String) weatherJson.get("weather"));
            lowest= (String) weatherRes.get((String) weatherJson.get("lowest"));
            highest= (String) weatherRes.get((String) weatherJson.get("highest"));
        }


        Long loveDayNum = DateUtils.getDatePoor(loveDay);
        Long babyBirthDayOff = DateUtils.birthDayOff(babyBirthDay);
        Long myBirthDayOff = DateUtils.birthDayOff(myBirthDay);
        //String rainbow=this.getRainbow();
        String astro = this.getAstro((String) paramsObject.get("astro"));
        String zaoan=this.getZaoAn();

        String token=getAccessToken();
        List<String> userList = getUserList(token);

        for (String openid:userList)
        {
            WechatSendMsgVo msgVo=new WechatSendMsgVo();
            msgVo.setTemplate_id(templateId);
            msgVo.setTouser(openid);
            Map<String, WechatTemplateVo> map = new HashMap<>();
            map.put("zaoan",new WechatTemplateVo("宝贝早安！"+zaoan,"#40a9ff"));
            map.put("date",new WechatTemplateVo(DateUtils.parseDateToStr("yyyy-MM-dd",new Date())));
            map.put("week",new WechatTemplateVo(DateUtils.getWeek(new Date())));
            map.put("area",new WechatTemplateVo(area));
            map.put("weather",new WechatTemplateVo(weather));
            map.put("lowest",new WechatTemplateVo(lowest+"℃"));
            map.put("highest",new WechatTemplateVo(highest+"℃"));
            map.put("loveDayNum",new WechatTemplateVo(String.valueOf(loveDayNum),"#ff4d4f"));
            map.put("babyBirthDayOff",new WechatTemplateVo(String.valueOf(babyBirthDayOff),"#ff4d4f"));
            map.put("myBirthDayOff",new WechatTemplateVo(String.valueOf(myBirthDayOff),"#ff4d4f"));
            map.put("fortune",new WechatTemplateVo(astro,"#40a9ff"));
            msgVo.setData(map);
            sendMessage(msgVo,token,openid);
        };

    }

    public String sendMessage(WechatSendMsgVo msgVo,String token,String openid){
        String url=Url.SEND_TEMPLATE.replace("ACCESS_TOKEN",token);
        HttpHeaders headers=new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        HttpEntity<String> httpEntity = new HttpEntity<>(JSONObject.toJSONString(msgVo).toString(), headers);
        String res = restTemplate.postForObject(url, httpEntity, String.class);
        logger.info("消息发送：用户："+openid+",结果:"+res);
        return res;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        String name=this.getClass().getSimpleName();
        Method[] declaredMethods = this.getClass().getDeclaredMethods();
        List<String> res=new ArrayList<>();
        for (int i = 0; i < declaredMethods.length; i++) {
            if(!"afterPropertiesSet".equals(declaredMethods[i].getName())) {
                res.add(declaredMethods[i].getName());
            }
        }
        char[] cs=name.toCharArray();
        cs[0]+=32;
        name=new String(cs);
        ScheduledUtils.serviceMap.put(name,res);
    }
}
